package com.dingup.homework.controller.manage;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dingup.api.Util.RedisUtils;
import com.dingup.api.base.HttpResContent;
import com.dingup.api.model.classInfo.ClassInfo;
import com.dingup.api.model.classInfo.ClassUserInfo;
import com.dingup.api.model.mock.home.SubjectNameDataMapInfo;
import com.dingup.homework.bean.DO.CorrectTeacher;
import com.dingup.homework.bean.DO.HwHomeworkDO;
import com.dingup.homework.bean.DO.HwHomeworkRecordDO;
import com.dingup.homework.bean.DO.HwHomeworkTeacherCorrectDO;
import com.dingup.homework.bean.DTO.HomeworkRecordDODataMapInfo;
import com.dingup.homework.bean.DTO.HwHomeworkDTO;
import com.dingup.homework.bean.HomeworkQuestion;
import com.dingup.homework.enums.HomeworkRecordStatusEnum;
import com.dingup.homework.enums.HomeworkStatusEnum;
import com.dingup.homework.enums.QuestionTypeEnum;
import com.dingup.homework.feign.client.classInfo.ClassInfoFeignClient;
import com.dingup.homework.feign.client.mock.MockFeignClient;
import com.dingup.homework.feign.client.user.UserFeignClient;
import com.dingup.homework.service.HwHomeworkRecordsService;
import com.dingup.homework.service.HwHomeworkService;
import com.dingup.homework.service.HwSsatWordService;
import com.dingup.homework.service.TeacherCorrectService;
import com.suyeer.basic.util.BHttpResUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.dingup.api.base.BaseUtil.*;
import static com.dingup.homework.util.ConstUtil.*;

/**
 * 班主任管理作业
 *
 * @author jun 2018/11/8.
 */
@Controller
@RequestMapping("/manage/homework")
public class ManageHomeworkController {

    private static final Logger logger = LoggerFactory.getLogger(ManageHomeworkController.class);

    @Autowired
    private HwHomeworkService hwHomeworkService;

    @Autowired
    private MockFeignClient mockFeignClient;

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private ClassInfoFeignClient classInfoFeignClient;

    @Autowired
    private HwSsatWordService hwSsatWordService;

    @Autowired
    private HwHomeworkRecordsService hwHomeworkRecordsService;

    @Autowired
    private TeacherCorrectService teacherCorrectService;

    @RequestMapping(value = "/list_homework.do", method = RequestMethod.POST)
    public void listHomeworkList(@RequestParam(PARAM_IF_HISTORY_HOMEWORK) Boolean ifHistoryHomework,
                                 HttpServletRequest request, HttpServletResponse response) {
        HttpResContent<List<HwHomeworkDTO>> hrc = new HttpResContent<>(request, response);
        hrc.setFuncDes("获取作业列表");
        try {
            // check.
            checkParam(PARAM_IF_HISTORY_HOMEWORK, ifHistoryHomework);
            // do.
            String userId = RedisUtils.getInstance().getUserId(request);
            List<HwHomeworkDTO> retList;
            if (ifHistoryHomework) {
                retList = hwHomeworkService.listHistoryHomework(userId);
            } else {
                retList = hwHomeworkService.listNormalHomework(userId);
            }
            // response.
            saveSuccessMsgAndData(hrc, retList);
        } catch (Exception e) {
            saveErrorMsgAndData(hrc, e);
        } finally {
            BHttpResUtil.writeResult(hrc);
        }
    }

    @RequestMapping(value = "/add_homework.do", method = RequestMethod.POST)
    public void addHomework(@RequestParam(PARAM_HOMEWORK_NAME) String homeworkName,
                            @RequestParam(PARAM_CLASS_ID) Integer classId,
                            @RequestParam(PARAM_STUDENT_IDS) String studentIds,
                            @RequestParam(PARAM_QUESTION_LIST) String questionList,
                            @RequestParam(PARAM_TEACHER_FOR_SPEAKING) String teacherForSpeaking,
                            @RequestParam(PARAM_TEACHER_FOR_WRITING) String teacherForWriting,
                            @RequestParam(PARAM_TEACHER_FOR_SUBJECTIVE) String teacherForSubjective,
                            @RequestParam(PARAM_EXPIRED_TIME) Long expiredTime,
                            HttpServletRequest request, HttpServletResponse response) {
        HttpResContent<Boolean> hrc = new HttpResContent<>(request, response);
        hrc.setFuncDes("添加作业");
        try {
            // check.
            checkParam(PARAM_HOMEWORK_NAME, homeworkName);
            checkParam(PARAM_CLASS_ID, classId);
            checkParam(PARAM_STUDENT_IDS, studentIds);
            checkParam(PARAM_QUESTION_LIST, questionList);
            checkParam(PARAM_EXPIRED_TIME, expiredTime);
            // do.
            String userId = RedisUtils.getInstance().getUserId(request);
            List<HomeworkQuestion> qList = JSON.parseArray(questionList, HomeworkQuestion.class);
            HwHomeworkDO hwHomework = new HwHomeworkDO();
            hwHomework.setHomeworkName(homeworkName);
            hwHomework.setClassId(classId);
            hwHomework.setStudentIds(JSON.parseArray(studentIds, String.class));
            hwHomework.setCreateUserId(userId);
            hwHomework.setQuestionList(qList);
            hwHomework.setHomeworkStatus(HomeworkStatusEnum.WAITING);
            hwHomework.setExpiredTime(new Date(expiredTime));
            hwHomework.setIfSubjective(qList.size() > 0 && qList.get(0).getQuestionType() == QuestionTypeEnum.SUBJECTIVE);
            hwHomework.setCorrectTeacher(new CorrectTeacher(teacherForSpeaking, teacherForWriting, teacherForSubjective));
            if (!hwHomeworkService.add(hwHomework)) {
                throw new Exception("保存数据入库失败!");
            }
            // response.
            saveSuccessMsgAndData(hrc, true);
        } catch (Exception e) {
            saveErrorMsgAndData(hrc, e);
        } finally {
            BHttpResUtil.writeResult(hrc);
        }
    }

    @RequestMapping(value = "/update_homework.do", method = RequestMethod.POST)
    public void updateHomework(@RequestParam(PARAM_HOMEWORK_ID) Integer homeworkId,
                               @RequestParam(PARAM_HOMEWORK_NAME) String homeworkName,
                               @RequestParam(PARAM_CLASS_ID) Integer classId,
                               @RequestParam(PARAM_STUDENT_IDS) String studentIds,
                               @RequestParam(PARAM_QUESTION_LIST) String questionList,
                               @RequestParam(PARAM_TEACHER_FOR_SPEAKING) String teacherForSpeaking,
                               @RequestParam(PARAM_TEACHER_FOR_WRITING) String teacherForWriting,
                               @RequestParam(PARAM_TEACHER_FOR_SUBJECTIVE) String teacherForSubjective,
                               @RequestParam(PARAM_EXPIRED_TIME) Long expiredTime,
                               HttpServletRequest request, HttpServletResponse response) {
        HttpResContent<Boolean> hrc = new HttpResContent<>(request, response);
        hrc.setFuncDes("编辑作业");
        try {
            // check.
            checkParam(PARAM_HOMEWORK_ID, homeworkId);
            checkParam(PARAM_CLASS_ID, classId);
            checkParam(PARAM_HOMEWORK_NAME, homeworkName);
            checkParam(PARAM_STUDENT_IDS, studentIds);
            checkParam(PARAM_QUESTION_LIST, questionList);
            checkParam(PARAM_EXPIRED_TIME, expiredTime);
            // do.
            HwHomeworkDO hwHomework = hwHomeworkService.getById(homeworkId);
            if (hwHomework == null) {
                throw new Exception("作业不存在或已删除");
            }
            if (hwHomework.getHomeworkStatus() != HomeworkStatusEnum.WAITING) {
                throw new Exception("作业不允许编辑");
            }
            List<HomeworkQuestion> qList = JSON.parseArray(questionList, HomeworkQuestion.class);
            hwHomework.setHomeworkName(homeworkName);
            hwHomework.setClassId(classId);
            hwHomework.setStudentIds(JSON.parseArray(studentIds, String.class));
            hwHomework.setQuestionList(qList);
            hwHomework.setCorrectTeacher(new CorrectTeacher(teacherForSpeaking, teacherForWriting, teacherForSubjective));
            hwHomework.setExpiredTime(new Date(expiredTime));
            hwHomework.setIfSubjective(qList.size() > 0 && qList.get(0).getQuestionType() == QuestionTypeEnum.SUBJECTIVE);
            if (!hwHomeworkService.update(hwHomework)) {
                throw new Exception("编辑数据入库失败!");
            }
            // response.
            saveSuccessMsgAndData(hrc, true);
        } catch (Exception e) {
            saveErrorMsgAndData(hrc, e);
        } finally {
            BHttpResUtil.writeResult(hrc);
        }
    }

    @RequestMapping(value = "/get_homework.do", method = RequestMethod.POST)
    public void getHomework(@RequestParam(PARAM_HOMEWORK_ID) Integer homeworkId,
                            HttpServletRequest request, HttpServletResponse response) {
        HttpResContent<JSONObject> hrc = new HttpResContent<>(request, response);
        hrc.setFuncDes("获取某次作业内容");
        try {
            // check.
            checkParam(PARAM_HOMEWORK_ID, homeworkId);
            // do.
            JSONObject retObj = new JSONObject();
            HwHomeworkDO hwHomework = hwHomeworkService.getById(homeworkId);
            if (hwHomework == null) {
                throw new Exception("作业不存在或已删除");
            }
            ClassInfo classInfo = classInfoFeignClient.getSimpleClassInfo(hwHomework.getClassId());
            JSONArray studentInHomework = new JSONArray();
            JSONArray studentNotInHomework = new JSONArray();
            for (ClassUserInfo classUserInfo : classInfo.getStudents()) {
                JSONObject obj = new JSONObject();
                obj.put(KEY_STUDENT_ID, classUserInfo.getUserId());
                obj.put(KEY_STUDENT_NAME, classUserInfo.getUserName());
                if (hwHomework.getStudentIds().contains(classUserInfo.getUserId())) {
                    studentInHomework.add(obj);
                } else {
                    studentNotInHomework.add(obj);
                }
            }
            retObj.put("hwHomework", hwHomework);
            retObj.put("studentInHomework", studentInHomework);
            retObj.put("studentNotInHomework", studentNotInHomework);
            // response.
            saveSuccessMsgAndData(hrc, retObj);
        } catch (Exception e) {
            saveErrorMsgAndData(hrc, e);
        } finally {
            BHttpResUtil.writeResult(hrc);
        }
    }

    @RequestMapping(value = "/delete_homework.do", method = RequestMethod.POST)
    public void deleteHomework(@RequestParam(PARAM_HOMEWORK_ID) Integer homeworkId,
                               HttpServletRequest request, HttpServletResponse response) {
        HttpResContent<Boolean> hrc = new HttpResContent<>(request, response);
        hrc.setFuncDes("删除作业");
        try {
            // check.
            checkParam(PARAM_HOMEWORK_ID, homeworkId);
            // do.
            HwHomeworkDO hwHomework = hwHomeworkService.getById(homeworkId);
            if (hwHomework == null) {
                throw new Exception("作业不存在或已删除");
            }
            if (hwHomework.getHomeworkStatus() != HomeworkStatusEnum.WAITING) {
                throw new Exception("该作业已分发, 不允许删除!");
            }
            Boolean ret = hwHomeworkService.delete(homeworkId);
            // response.
            saveSuccessMsgAndData(hrc, ret);
        } catch (Exception e) {
            saveErrorMsgAndData(hrc, e);
        } finally {
            BHttpResUtil.writeResult(hrc);
        }
    }

    @RequestMapping(value = "/assign_homework.do", method = RequestMethod.POST)
    public void assignHomework(@RequestParam(PARAM_HOMEWORK_ID) Integer homeworkId,
                               @RequestParam(PARAM_STUDENT_IDS) String studentIds,
                               HttpServletRequest request, HttpServletResponse response) {
        HttpResContent<Boolean> hrc = new HttpResContent<>(request, response);
        hrc.setFuncDes("分发作业");
        try {
            // check.
            checkParam(PARAM_HOMEWORK_ID, homeworkId);
            checkParam(PARAM_STUDENT_IDS, studentIds);
            // do.
            HwHomeworkDO hwHomework = hwHomeworkService.getById(homeworkId);
            if (hwHomework == null) {
                throw new Exception("作业不存在或已删除");
            }
            if (hwHomework.getHomeworkStatus() == HomeworkStatusEnum.FINISHED) {
                throw new Exception("作业已归档");
            }
            hwHomework.setStudentIds(JSON.parseArray(studentIds, String.class));
            if (!hwHomeworkService.update(hwHomework)) {
                throw new Exception("编辑数据入库失败!");
            }
            // 1. 修改作业状态
            hwHomeworkService.assignHomework(homeworkId);
            logger.info("修改作业状态完成, homeworkId={}", homeworkId);
            // 2. 添加学生记录
            hwHomeworkRecordsService.addHomeworkRecord(hwHomework);
            logger.info("添加学生记录完成, homeworkId={}", homeworkId);
            // response.
            saveSuccessMsgAndData(hrc, true);
        } catch (Exception e) {
            saveErrorMsgAndData(hrc, e);
        } finally {
            BHttpResUtil.writeResult(hrc);
        }
    }

    @RequestMapping(value = "/list_homework_record.do", method = RequestMethod.POST)
    public void listHomeworkRecord(@RequestParam(PARAM_HOMEWORK_ID) Integer homeworkId,
                                   HttpServletRequest request, HttpServletResponse response) {
        HttpResContent<List<HomeworkRecordDODataMapInfo>> hrc = new HttpResContent<>(request, response);
        hrc.setFuncDes("获取某个作业的所有学生的作业记录");
        try {
            // check.
            checkParam(PARAM_HOMEWORK_ID, homeworkId);
            // do.
            List<HomeworkRecordDODataMapInfo> retList = hwHomeworkRecordsService.listByHomeworkId(homeworkId);
            saveSuccessMsgAndData(hrc, retList);
        } catch (Exception e) {
            saveErrorMsgAndData(hrc, e);
        } finally {
            BHttpResUtil.writeResult(hrc);
        }
    }

    @RequestMapping(value = "/get_subject_name.do", method = RequestMethod.POST)
    public void getSubjectName(@RequestParam(PARAM_EXAM_CONTENT_TYPE) String examContentType,
                               HttpServletRequest request, HttpServletResponse response) {
        HttpResContent<Map<String, List<SubjectNameDataMapInfo>>> hrc = new HttpResContent<>(request, response);
        hrc.setFuncDes("获取托福模考标题");
        try {
            // check.
            checkParam(PARAM_EXAM_CONTENT_TYPE, examContentType);
            // do.
            Map<String, List<SubjectNameDataMapInfo>> retMap = mockFeignClient.getSubjectName(examContentType.toUpperCase());
            // response.
            saveSuccessMsgAndData(hrc, retMap);
        } catch (Exception e) {
            saveErrorMsgAndData(hrc, e);
        } finally {
            BHttpResUtil.writeResult(hrc);
        }
    }

    @RequestMapping(value = "/list_ssat_paper.do", method = RequestMethod.POST)
    public void listSsatPaper(HttpServletRequest request,
                              HttpServletResponse response) {
        HttpResContent<JSONArray> hrc = new HttpResContent<>(request, response);
        hrc.setFuncDes("获取SSAT套题列表");
        try {
            // do.
            List<Integer> list = hwSsatWordService.listPaper();
            JSONArray retArr = new JSONArray();
            for (Integer i : list) {
                JSONObject obj = new JSONObject();
                obj.put(KEY_LABEL, "SSAT词汇真题 " + i);
                obj.put(KEY_VALUE, i);
                retArr.add(obj);
            }
            // response.
            saveSuccessMsgAndData(hrc, retArr);
        } catch (Exception e) {
            saveErrorMsgAndData(hrc, e);
        } finally {
            BHttpResUtil.writeResult(hrc);
        }
    }

    @RequestMapping(value = "/update_homework_correct_teacher.do", method = RequestMethod.POST)
    public void updateHomeworkCorrectTeacher(HttpServletRequest request,
                                             HttpServletResponse response,
                                             CorrectTeacher correctTeacher) {
        HttpResContent<Boolean> hrc = new HttpResContent<>(request, response);
        hrc.setFuncDes("修改作业的批改老师");
        try {
            Boolean res = hwHomeworkService.updateCorrectTeacher(correctTeacher.getHomeworkId(), correctTeacher);
            saveSuccessMsgAndData(hrc, res);
        } catch (Exception e) {
            saveErrorMsgAndData(hrc, e);
        } finally {
            BHttpResUtil.writeResult(hrc);
        }
    }

    @RequestMapping(value = "/get_user_name.do", method = RequestMethod.POST)
    public void getUserName(HttpServletRequest request,
                            HttpServletResponse response,
                            String userId) {
        HttpResContent<String> hrc = new HttpResContent<>(request, response);
        hrc.setFuncDes("获取用户姓名");
        try {
            String userName = userFeignClient.getUserNameByUserId(userId);
            saveSuccessMsgAndData(hrc, userName);
        } catch (Exception e) {
            saveErrorMsgAndData(hrc, e);
        } finally {
            BHttpResUtil.writeResult(hrc);
        }
    }

    /**
     * 保存老师批改作业数据
     * 该接口中的批改文档属于可选参数
     *
     * @param homeworkRecordId Integer
     * @param docUrl           String
     * @param request          HttpServletRequest
     * @param response         HttpServletResponse
     */
    @RequestMapping(value = "/save_correction.do", method = RequestMethod.POST)
    public void saveCorrection(@RequestParam(PARAM_HOMEWORK_RECORD_ID) Integer homeworkRecordId,
                               @RequestParam(PARAM_DOC_URL) String docUrl,
                               HttpServletRequest request, HttpServletResponse response) {
        HttpResContent<Boolean> hrc = new HttpResContent<>(request, response);
        hrc.setFuncDes("保存老师批改数据");
        try {
            // check.
            checkParam(PARAM_HOMEWORK_RECORD_ID, homeworkRecordId);
            // do.
            String userId = RedisUtils.getInstance().getUserId(request);
            HwHomeworkRecordDO thr = hwHomeworkRecordsService.getById(homeworkRecordId);
            if (thr == null) {
                throw new Exception("获取学生作业记录[" + homeworkRecordId + "]失败.");
            }
            thr.setCorrectionDocUrl(docUrl);
            thr.setCorrectionTeacherId(userId);
            thr.setCorrectionTime(new Date());
            thr.setStatus(HomeworkRecordStatusEnum.CORRECTED);
            if (!hwHomeworkRecordsService.update(thr)) {
                throw new Exception("更新老师批改数据失败.");
            }
            //更新老师批改作业列表状态  主观题只有一道题
            HwHomeworkTeacherCorrectDO param = new HwHomeworkTeacherCorrectDO();
            param.setHomeworkRecordId(homeworkRecordId);
            param.setStudentId(thr.getStudentId());
            param.setTeacherId(userId);
            HwHomeworkTeacherCorrectDO tts = teacherCorrectService.getByBean(param);
            if (tts != null) {
                teacherCorrectService.updateCorrectHomeworkStatus(tts.getId(), HomeworkStatusEnum.CORRECTED);
            }
            // result.
            saveSuccessMsgAndData(hrc, true);
        } catch (Exception e) {
            saveErrorMsgAndData(hrc, e);
        } finally {
            BHttpResUtil.writeResult(hrc);
        }
    }
}
